//
//  AP_NSMutableAttributedString_Extension.swift
//  APSwift
//
//  Created by jianbo.pei on 2022/3/9.
//

import Foundation
import UIKit

extension NSMutableAttributedString {
    fileprivate struct AssociatedKeys {
        static var fontKey = UnsafeRawPointer("fontKey".withCString({ $0 }))
        static var textColorKey = UnsafeRawPointer("textColorKey".withCString({ $0 }))
    }
    
    //MARK: 获取所有文字range
    public func allRange() -> NSRange {
        return NSMakeRange(0, self.length)
    }
    
    //MARK: 设置字体
    public var font: UIFont? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.fontKey) as? UIFont
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.fontKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            guard let newValue = newValue else { return }
            add(font: newValue, range: allRange())
        }
    }
    
    public func add(font: UIFont, range: NSRange) {
        addAttribute(.font, value: font, range: range)
    }
    
    //MARK: 设置文字颜色
    public var textColor: UIColor? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.textColorKey) as? UIColor
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.textColorKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            guard let newValue = newValue else { return }
            add(textColor: newValue, range: allRange())
        }
    }
    
    public func add(textColor: UIColor, range: NSRange) {
        addAttribute(.foregroundColor, value: textColor, range: range)
    }
    
    public func special(text: String, font: UIFont, textColor: UIColor) {
        let range = (string as NSString).range(of: text)
        add(font: font, range: range)
        add(textColor: textColor, range: range)
    }
    
    public func special(texts: [String], fonts: [UIFont], textColors: [UIColor]) {
        guard texts.count == fonts.count && fonts.count == textColors.count else {
            #if DEBUG
            
            #endif
            return
        }
        var recordIndexDict: [String: [Int]] = [:]
        var recordRangeDict: [String: [NSRange]] = [:]
        for (idx, str) in texts.enumerated() {
            if recordIndexDict.keys.contains(str) {
                /// ranges这里不用处理
                if let indexs = recordIndexDict[str] {
                    var idxs: [Int] = []
                    idxs.append(contentsOf: indexs)
                    idxs.append(idx)
                    recordIndexDict[str] = idxs
                }
            } else {
                /// `recordIndexDict`中不含当前字符串
                let nsranges = string.nsranges(of: str)
                if nsranges.count > 0 {
                    let indexs: [Int] = [idx]
                    recordIndexDict[str] = indexs
                    recordRangeDict[str] = nsranges
                }
            }
        }
        
        for (key, value) in recordIndexDict {
            if value.count > 0, let rangeValue = recordRangeDict[key] {
                for idx in 0..<value.count {
                    let index = value[idx]
                    let range = rangeValue[idx]
                    add(font: fonts[index], range: range)
                    add(textColor: textColors[index], range: range)
                }
            }
        }
        
    }
    
}

extension NSMutableAttributedString {
    func append(_ str: String, font: UIFont, textColor: UIColor) {
        let mutAtt = NSMutableAttributedString(string: str)
        mutAtt.add(font: font, range: mutAtt.allRange())
        mutAtt.add(textColor: textColor, range: mutAtt.allRange())
        append(mutAtt)
    }
}
